package com.example.wxsmart.util;

import com.alibaba.fastjson.JSON;
import com.example.wxsmart.pojo.User;
import io.jsonwebtoken.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Luojunxian
 * @data 2022/7/7 13:57
 * @classname JwtUtil
 */
@Slf4j
@Component
public class JwtUtil {

    /**
     * token过期时间一个月(毫秒)
     */
    private static final long TOKEN_EXPIRE_TIME = 30 * 24 * 60 * 60 * 1000;

    /**
     * 用户过期时间5分钟(秒)
     */
    private static final long REDIS_EXPIRE_TIME = 2 * 60 * 60;

    /**
     * 加密密钥
     */
    private static final String KEY = "FJSADFHEIGSAGSFLSDCMASFN";

    /**
     * redis_key前缀
     */
    private static final String REDIS_KEY = "user:";

    @Resource
    private RedisUtil redisUtil;

    /**
     * 根据用户信息生成token
     *
     * @param user 用户名
     * @return
     */
    public static String createToken(User user) {
        Map<String, Object> header = new HashMap(2);
        header.put("typ", "JWT");
        header.put("alg", "HS256");
        //setID:用户ID
        //setExpiration:token过期时间  当前时间+有效时间
        //setSubject:用户名
        //setIssuedAt:token创建时间
        //signWith:加密方式
        return Jwts.builder().setHeader(header)
                .setId(user.getId().toString())
                .setExpiration(new Date(System.currentTimeMillis() + TOKEN_EXPIRE_TIME))
                .setSubject(JSON.toJSONString(user))
                .setIssuedAt(new Date())
                .signWith(SignatureAlgorithm.HS256, KEY)
                .compact();
    }

    /**
     * 根据token获取存储的用户信息
     * @param token
     * @return
     */
    public static User checkToken(String token) {
        Claims claims;
        try {
            claims = Jwts.parser().setSigningKey(KEY).parseClaimsJws(token).getBody();
        } catch (Exception e) {
            return null;
        }

        return JSON.parseObject(claims.getSubject(), User.class);
    }

    /**
     * ------------------------------------------------------------------------------------------------------------
     * 以下为redis校验token
     */

    /**
     * 保存键token值用户信息到redis
     * @param token
     * @param user
     * @return
     */
    public boolean saveToken(String token, User user) {
        return redisUtil.set(REDIS_KEY + token, user, REDIS_EXPIRE_TIME);
    }

    /**
     * 更新键token时间
     * @param token
     * @return
     */
    public boolean refreshTokenTime(String token) {
        return redisUtil.expire(REDIS_KEY + token, REDIS_EXPIRE_TIME);
    }
}
